<template>
  <!-- WEB端 -->
  <div
    :class="['client-side-wrap', { 'is-experience': isExperience }]"
    v-if="!isMobile"
  >
    <div class="client-side-wrap__header" v-if="!isExperience">
      <div class="header-logo-container">
        <a href="javascript:;">
          <div class="logo"></div>
        </a>
        <a href="javascript:;">
          <div class="project-name">知识库小助手</div>
        </a>
      </div>
      <div
        v-if="isPhoneUser"
        class="header-menu-container"
        v-popmenu:menu.click
      >
        <div class="user-img"><img :src="userAvatar" /></div>
        <span v-if="userName">{{ userName }}</span>
        <v-icon remote name="arrow_down_small_fill" size="12"></v-icon>
        <v-popmenu
          ref="menu"
          :options="menuOptions"
          @select="handleSelect"
          placement="bottom-end"
          clazz="user-menu"
        >
          <template slot="item" slot-scope="prop">
            <div class="menu-item">
              <span>{{ prop.item.text }}</span>
            </div>
          </template>
        </v-popmenu>
      </div>
    </div>
    <div class="client-side-wrap__main">
      <div class="client-side-wrap__main-right">
        <div class="chat-wrap is-web">
          <div
            v-if="!isAvailable || !tokenEnough"
            class="chat-wrap__main unavailable"
          >
            <Unavailable
              :tip="!tokenEnough ? '应用暂停服务' : '应用暂未发布'"
            />
          </div>
          <div
            v-else
            :class="`${
              isWorkspaceActive ? 'chat-layout workspace-active' : 'chat-layout'
            }`"
          >
            <div
              :class="[
                'chat-wrap__main',
                { 'experience-height': isExperience },
                { 'is-voice': isVoice },
              ]"
            >
              <!-- <div :class="['chat-wrap__main', {'experience-height': isExperience}]"> -->
              <div
                :class="
                  !isVoice
                    ? 'chat-wrap__main-header'
                    : 'chat-wrap__main-header is-voice'
                "
              >
                <ChatHeader
                  @reset="onResetChat"
                  @autoPlayChange="onAutoPlayChange"
                  :showReset="isAvailable"
                  :transferStatus="transferStatus"
                  :transferAvatar="transferAvatar"
                  @startCall="startCall"
                  :isVoice="isVoice"
                  :autoPlay="autoPlay"
                />
              </div>
              <div class="bg-container">
                <div v-if="isExperience" class="chat-wrap__main-head">
                  <RelatedDoc :doc-list="relatedDocList" />
                </div>
                <div
                  v-show="!isVoice"
                  class="chat-wrap__main-content"
                  :style="{ 'margin-bottom': `${chatMainMrgBottom}px` }"
                >
                  <RobotUnavailable v-if="!isAvailable" />
                  <ClientChat
                    v-if="isAvailable"
                    @send="onSendQuestion"
                    @openBottomDrawer="openBottomDrawer"
                    :autoPlay="autoPlay"
                    @toggleworkspace="toggleworkspace"
                    @openWorkspace="openWorkspace"
                    :workspaceVisible="workspaceVisible"
                  />
                </div>
                <div class="chat-wrap__main-footer" v-show="!isVoice">
                  <QuestionInput
                    ref="questionInputRef"
                    v-if="isAvailable"
                    @send="onSendQuestion"
                    @asrClick="onAsrClick"
                    :wordLimit="wordLimit"
                    :hasDynamicWordLimit="hasDynamicWordLimit"
                    :isExperience="isExperience"
                    :isASRActive="isASRActive"
                    :enableVoiceInteract="enableVoiceInteract && isASRReady"
                    :isReading="isReading"
                  />
                </div>
                <client-voice v-if="isVoice" @stopVoice="stopVoice" />
              </div>
              <BottomDrawer :isOpen.sync="isOpen">
                <div style="margin-bottom: 10px">
                  <MdComponent
                    v-if="isOpen && !isVoice"
                    :refer-ids="mdContent.ids"
                    :title="mdContent.name"
                    :type="mdContent.type"
                    :url="mdContent.url"
                    :row="mdContent"
                  ></MdComponent>
                </div>
              </BottomDrawer>
            </div>
            <work-space
              ref="workspace"
              :showData="workspaceData"
              v-if="isAgentPattern && !isMobile"
              v-model="workspaceVisible"
            />
          </div>
        </div>
      </div>
    </div>
    <div class="client-side-wrap__footer" v-if="!isVoice">
      <ServiceAgreement />
    </div>
  </div>

  <!-- 移动端 -->
  <div
    :class="['chat-wrap', 'is-mobile', { 'is-experience': isExperience }]"
    v-else
  >
    <div
      v-if="!isAvailable || !tokenEnough"
      class="chat-wrap__main unavailable"
    >
      <Unavailable :tip="!tokenEnough ? '应用暂停服务' : '应用暂未发布'" />
    </div>
    <div v-else class="chat-wrap__main">
      <div class="chat-wrap__main-header">
        <ChatHeader
          @reset="onResetChat"
          @autoPlayChange="onAutoPlayChange"
          :showReset="isAvailable"
          :transferStatus="transferStatus"
          :transferAvatar="transferAvatar"
          @startCall="startCall"
          :isVoice="isVoice"
          :autoPlay="autoPlay"
        />
      </div>
      <div class="bg-container" v-show="!isVoice">
        <div v-if="isExperience" class="chat-wrap__main-head">
          <RelatedDoc />
        </div>
        <div
          :class="
            isWelcome
              ? 'chat-wrap__main-content'
              : 'chat-wrap__main-chat-content'
          "
          :style="{ 'margin-bottom': `${chatMainMrgBottom}px` }"
        >
          <RobotUnavailable v-if="!isAvailable" />
          <ClientChat
            v-else
            @send="onSendQuestion"
            @openWorkspace="openWorkspace"
            @toggleworkspace="toggleworkspace"
            @openBottomDrawer="openBottomDrawer"
            :autoPlay="autoPlay"
          />
        </div>
        <div class="chat-wrap__main-footer">
          <QuestionInputMobile
            ref="questionInputMobileRef"
            v-if="isAvailable"
            v-show="!isASRActive"
            @send="onSendQuestion"
            :wordLimit="wordLimit"
            :isExperience="isExperience"
            @recording="onRecording"
            :enableVoiceInteract="enableVoiceInteract && isASRReady"
            @cancel="onMobileVoiceCanel"
          />
          <AsrAnimationMobile
            v-show="enableVoiceInteract && isASRActive"
            @cancel="onMobileVoiceCanel"
            @send="onMobileVoiceSend"
          />
          <ServiceAgreement class="service-agreement" :small="true" />
        </div>
      </div>
      <client-voice v-if="isVoice" @stopVoice="stopVoice" />
      <BottomDrawer :isOpen.sync="isOpen">
        <div style="margin-bottom: 10px">
          <MdComponent
            v-if="isOpen"
            :refer-ids="mdContent.ids"
            :title="mdContent.name"
            :type="mdContent.type"
            :url="mdContent.url"
            :row="mdContent"
          >
          </MdComponent>
        </div>
      </BottomDrawer>
    </div>
  </div>
</template>

<script>
import Unavailable from "@/components/Unavailable";
import ServiceAgreement from "./components/service-agreement.vue";
import RobotUnavailable from "./components/robot-unavailable.js";
import ChatHeader from "./components/chat-header";
import ClientChat from "./components/client-chat";
import QuestionInput from "./components/question-input";
import QuestionInputMobile from "./components/quesion-input-mobile";
import { MESSAGE_TYPE, APP_TYPE } from "@/constants";
import BottomDrawer from "./components/bottom-drawer.vue";
import MdComponent from "./components/md.vue";
import { getQueryVariable } from "@/utils";
import RelatedDoc from "./components/related-doc.vue";
import AsrAnimationMobile from "./components/asr-animation-mobile.vue";
import ClientVoice from "./components/client-voice";
export default {
  name: "ClientSide",
  components: {
    ClientVoice,
    RelatedDoc,
    RobotUnavailable,
    ChatHeader,
    ClientChat,
    QuestionInput,
    QuestionInputMobile,
    BottomDrawer,
    MdComponent,
    Unavailable,
    ServiceAgreement,
    AsrAnimationMobile
  },
  data() {
    const appType =
      this.webIMSource === "client"
        ? window.localStorage.getItem("app_type")
        : getQueryVariable("app_type");
    const isExperience = getQueryVariable("experience");
    return {
      isVoice: false,
      isAvatar: true,
      autoPlay: false,
      userAvatar: "",
      userName: "",
      isAvailable: true, // 默认已配置机器人和问答库，非维护中状态
      isWelcome: false,
      botBizId: 0,
      sessionId: "",
      transferStatus: null, // 当前转人工状态
      transferAvatar: "", // 转人工的头像
      chatMainMrgBottom: 140,
      isOpen: false,
      openId: "",
      mdContent: [],
      wordLimit: 0,
      appType,
      isExperience,
      relatedDocList: [],
      hasDynamicWordLimit:
        appType === APP_TYPE.CLASSIFYS || appType === APP_TYPE.SUMMARY,
      menuOptions: [{ text: "退出登录", value: "logout" }],
      questionInputMobileRef: null,
      questionInputRef: null,
      isASRActive: false,
      isCancelFromAsr: false,
      enableVoiceInteract: false,
      isReading: false,
      // ASR 的 临时密钥是否过期
      // 0：初始值，未过期
      // 1：上次的状态为过期
      isAsrTokenExpired: 0,
      isAgentPattern: false,
      workspaceVisible: false,
      workspaceData: null,
      // 当前 ASR 初始化完成
      isASRReady: false,
      isCurrentASREnd: true,
      currentTimer: null,
    };
  },
  mounted() {
    // 初始化数据
    this.$clientData.init();
    this.getRelatedDocList();
    this.$clientData.getWordCount().then((limit) => {
      this.wordLimit = limit;
    });
    const cachedConfig = this.$clientData.getConfigInfo();
    if (cachedConfig && cachedConfig.ai_call) {
      this.enableVoiceInteract = cachedConfig.ai_call.enable_voice_interact;
      if (this.webIMSource === "manage") {
        this.autoPlay = false;
      } else {
        this.autoPlay = cachedConfig.auto_play !== "disable";
      }
    }
    // 监听配置信息变更，获取机器人名称
    this.$eventHub.$on("client_configChange", (res) => {
      if (res.ai_call) {
        this.enableVoiceInteract = res.ai_call.enable_voice_interact;
        if (this.webIMSource === "manage") {
          this.autoPlay = false;
        } else {
          this.autoPlay = res.auto_play !== "disable";
        }
      }
    });
    // this.$eventHub.$on('ai_config_change', (res) => {
    //     const { enable_voice_interact } = res.aiconfig;
    //     this.enableVoiceInteract = enable_voice_interact;
    // });
    this.$nextTick(() => {
      if (document.querySelector(".question-input")) {
        if (this.isMobile) {
          this.chatMainMrgBottom =
            document.querySelector(".question-input").clientHeight - 134;
        } else {
          this.chatMainMrgBottom =
            document.querySelector(".question-input").clientHeight - 94;
        }
      }
    });

    const avatar = localStorage.getItem("user_avatar");
    const name = localStorage.getItem("user_name");
    if (avatar) {
      this.userAvatar = avatar;
    }
    if (name) {
      this.userName = name;
    }
  },
  created() {
    const webimToken = window.webimToken[0] || {};
    const isAgentPattern = webimToken.pattern && webimToken.pattern === "agent";
    this.isAgentPattern = isAgentPattern;
    // 监听用户端ws事件
    this.listenClientEvent();
    // 监听公共的ws事件
    this.listenCommonEvent();

    this.$eventHub.$on("reading_audio", ({ reading }) => {
      this.isReading = reading;
    });
  },
  beforeDestroy() {
    this.onAsrStop();
    this.asrInstance = null;
  },
  computed: {
    auditReferences() {
      let result = [];
      if (this.mdContent && this.mdContent.ids) {
        this.mdContent.ids.forEach((id) => {
          result.push({
            id,
            name: this.mdContent.name,
            type: this.mdContent.type,
            url: this.mdContent.url,
          });
        });
      }
      return result;
    },
    tokenEnough() {
      const token_balance = window.localStorage.getItem("balance");
      return token_balance && token_balance > 0;
    },
    isWorkspaceActive() {
      return this.isAgentPattern && this.workspaceVisible && !this.isMobile;
    },
  },
  watch: {
    enableVoiceInteract(val) {
      console.log("enableVoiceInteract======", val);
      if (val) {
        // 创建语音识别实例
        this.onCreateAsrInstance();
      }
    },
  },
  methods: {
    async stopVoice() {
      this.isVoice = false;
      // todo 获取历史记录
    },
    async startCall() {
      this.isVoice = true;
    },
    onAutoPlayChange(val) {
      this.autoPlay = val;
    },
    async getRelatedDocList() {
      // 只在体验中心的知识问答管理类型App时触发
      if (!(this.isExperience && this.appType === APP_TYPE.QA)) {
        return;
      }
      const botBizId = getQueryVariable("bot_biz_id");
    },
    getAuditReferDocCollapseTitleParams(index, item) {
      const total = this.auditReferences.length;
      return `参考文档 ${index + 1}${total > 1 ? "/" + total : ""}：${
        item.name
      }`;
    },
    openBottomDrawer(isOpen, refer) {
      this.isOpen = isOpen;
      this.mdContent = refer;
      if (this.mdContent && this.mdContent.ids) {
        this.openId = this.mdContent.ids[0];
      }
    },
    // 监听用户端ws事件
    listenClientEvent() {
      // 监听配置信息，获取机器人和问答库可用状态
      this.$eventHub.$on("client_configChange", (res) => {
        this.isAvailable = res.is_available; // 机器人与问答库是否可用，不可用则页面展示”维护中“状态
        this.botBizId = res.bot_biz_id;
        this.sessionId = res.session_id;
        if (
          res.app_type === APP_TYPE.SUMMARY ||
          res.app_type === APP_TYPE.CLASSIFYS
        ) {
          this.wordLimit = res.chat_words_limit;
        }
        // 拉取历史数据，若 >0 则隐藏欢迎页，并正在会话页展示本次拉取的 15 条历史数据
        this.$clientData.getHistory();
      });

      // 监听历史记录拉取成功事件
      this.$eventHub.$on("client_msgContentChange", (res) => {
        const { chatsContent, type } = res;
        if (type === MESSAGE_TYPE.ANSWER && chatsContent.length > 0) {
          // 主动推送记录数目录数 > 0，则隐藏欢迎页，进入绘会话页，并展示拉取的历史记录
          this.isWelcome = false;
        }
        if (type === MESSAGE_TYPE.HISTORY && chatsContent.length > 0) {
          // 历史记录数 > 0，则隐藏欢迎页，进入绘会话页，并展示拉取的历史记录
          this.isWelcome = false;
        }
      });
      // 监听历史记录拉取成功事件
      this.$eventHub.$on("data_transferInfo", (res) => {
        this.transferStatus = res.transferStatus;
        this.transferAvatar = res.transferAvatar;
      });
      // 监听历史记录拉取成功事件 res
      this.$eventHub.$on("session_reset", (data) => {
        console.log("是否仅清空会话关联---->", data);
        // gss要求，所有情况对话，都要停止生成
        this.$clientData.stopGeneration();
        if (data.session_disassociated_timestamp) {
          this.$clientData.breakReleation(data.session_disassociated_timestamp);
        } else {
          // this.isWeclome = true;
          this.$clientData.clearCache(); // 清空前端对话消息队列
          this.$clientData.queryConfigInfo(); // 重新生成session_id
        }
      });
    },
    // 监听公共的ws事件
    listenCommonEvent() {
      // 监听ws报错
      this.$eventHub.$on("client_systemEvents", (res) => {
        if (!res || !res.error) return;

        const { code, message } = res.error;
        this.$message.error(`${code}：${message}`);
      });
    },
    // 重新体验
    async onResetChat(val) {
      // IsOnlyEmptyTheDialog 是否仅清空会话关联
      console.log("是否仅清空会话关联", val, this.sessionId);
      console.log("onResetChat", val);
      try {
        if (val == "IsOnlyEmptyTheDialog") {
        } else {
          this.$clientData.clearCache(); // 清空前端对话消息队列
        }
        // 清空本地缓存的session即可
      } catch (error) {
        console.log(error);
        this.$message.error("重新体验异常，请重试");
      }
      this.toggleworkspace(false);
      //   this.$refs.workspace.resetMsg();
    },
    // 发送问题上行消息
    onSendQuestion(question, docUrls) {
      console.log("onSendQuestion", question, docUrls);
      this.isWelcome = false; // 输入问题后，由欢迎页切换至对话页
      this.$clientData.triggerSendMsg(question, docUrls);
    },
    async handleSelect({ option: { value } }) {
      if (value === "logout") {
        try {
          await this.$ajax.post("Logout");
          window.location.reload(); // 通过接口返回的19001跳转登录页
        } catch (error) {
          console.error(error);
        }
      }
    },
    async onAsrStart() {
      // 开始的时候需要检测关闭音频播放
      this.$eventHub.$emit("reading_audio", {
        reading: false,
      });
      // 通知语音输入开始，这时候语音播报应该是禁用状态
      this.$eventHub.$emit("voice_input", {
        isRecording: true,
      });
      if (this.asrInstance) {
        this.isCurrentASREnd = false;
        await this.asrInstance.wait2Start();
        this.isASRActive = true;
      } else {
        console.error("ASR is not supported or instance not available.");
      }
    },
    // 这个是个异步的方法，需要在 OnSentenceBegin 之后调用
    async onAsrStop() {
      // 通知语音输入结束，这时候语音播报应该是可用的状态
      this.$eventHub.$emit("voice_input", {
        isRecording: false,
      });
      if (this.asrInstance) {
        await this.asrInstance.wait2Stop();
        this.isASRActive = false;
        this.isCurrentASREnd = true;
      }
    },
    onAsrClick({ canRecording }) {
      if (this.isASRActive) {
        this.onAsrStop();
      } else {
        // 上一个识别未结束就不要进行下一次识别
        if (!this.isCurrentASREnd) return;
        if (canRecording) {
          this.onAsrStart();
        } else {
          this.$message.warning("回答中，请稍后操作或点击停止回答");
        }
      }
    },
    async onMobileVoiceSend() {
      this.isCancelFromAsr = false;
      this.onAsrStop();
    },
    async onMobileVoiceCanel() {
      this.isCancelFromAsr = true;
      this.onAsrStop();
    },
    onRecording({ canRecording }) {
      if (canRecording) {
        // 如果上一个timer 还没倒计时结束，则忽略
        if (this.currentTimer) {
          clearInterval(this.currentTimer);
          this.currentTimer = null;
        }

        if (this.isCurrentASREnd) {
          // 上一个识别已经结束，直接开始
          this.onAsrStart();
        } else {
          // 要等上一个识别结束后才能开始新的识别
          this.currentTimer = setInterval(() => {
            if (this.isCurrentASREnd) {
              clearInterval(this.currentTimer);
              this.currentTimer = null;
              this.onAsrStart();
            }
          }, 100);
        }
      } else {
        this.$toast({
          message: "回答中，请稍后操作或点击停止回答",
          duration: 3,
          tdom: document.body,
          isShowIcon: false,
        });
      }
    },
    onCreateAsrInstance() {
    },
    toggleworkspace(bool) {
      if (!bool) {
        this.workspaceData = null;
      }
      // gpt-demo中已经打开参考来源，需要关掉 workspace
      this.workspaceVisible = !!bool;
    },
    openWorkspace(data, procedureIndex) {
      this.workspaceData = { data, procedureIndex };
    },
  },
};
</script>

<style lang="less">
.voice-bg {
  border-radius: 6px;
  background: linear-gradient(
      125deg,
      rgba(255, 239, 250, 0.8) 21.83%,
      #def5ff 79.71%
    ),
    #fff;
  // background: linear-gradient(125deg, color(display-p3 1 0.9381 0.9783 / 0.80) 21.83%, color(display-p3 0.8893 0.9594 1) 79.71%), color(display-p3 1 1 1);
}

.user-menu {
  top: 56px !important;

  .menu-item {
    display: flex;
    gap: 8px;
    align-items: center;
    cursor: pointer;
    height: 25px;
    padding: 0 var(--spacing-base);
    overflow: hidden;
    line-height: 30px;
    text-overflow: ellipsis;

    &.account {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      height: 50px;
    }
  }

  .iconImg {
    display: inline-block;
    width: 16px;
    height: 16px;

    &:hover {
      cursor: pointer;
    }
  }
}

.chat-wrap__main-header.is-voice {
  z-index: 2;

  .header-banner.header-banner-bg {
    background: transparent;
  }
}

.client-side-wrap {
  * {
    box-sizing: border-box;
  }

  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  min-width: 480px;
  overflow-x: hidden;

  background: url("../../assets/img/bg-c2.png");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;

  &__header {
    height: 56px;
    width: 100%;
    margin-bottom: var(--spacing-super-loose);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-base-loose) var(--spacing-quite-loose);
    background-color: #ffffff;
    box-shadow: 0px 0px 1px rgba(18, 19, 25, 0.08),
      0px 0px 2px rgba(18, 19, 25, 0.08), 0px 2px 4px rgba(18, 19, 25, 0.08);

    .header-logo-container {
      display: flex;
      align-items: center;

      > a {
        text-decoration: none;
      }

      .project-name {
        color: var(--color-text-primary);
        font-family: "PingFang SC";
        font-size: 16px;
        font-style: normal;
        font-weight: 600;
        line-height: 24px;

        /* 150% */
        &::before {
          content: "|";
          font-size: 18px;
          margin: 0 16px;
          opacity: 0.3;
        }
      }
    }

    .logo {
      height: 32px;
      vertical-align: middle;
      width: 104px;
      // background: url(../../assets/img/lke-logo.svg) no-repeat center / cover;
    }

    .header-menu-container {
      padding: 0 4px;
      border-radius: 3px;
      height: 32px;
      display: flex;
      gap: 4px;
      align-items: center;
      cursor: pointer;
      color: var(--text---color-text-primary, rgba(0, 1, 11, 0.93));
      text-align: center;
      font: var(--body-regular);

      &:hover {
        background-color: var(--color-fill-hover);
      }

      &:active {
        background-color: var(--color-fill-active);
      }

      .user-img {
        width: 28px;
        height: 28px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;

        img {
          width: 28px;
          height: 28px;
          border-radius: 50%;
        }
      }
    }
  }

  &__main {
    flex: 1;
    position: relative;
    display: flex;
    padding: 0 var(--spacing-super-loose);
    width: 100%;
    height: calc(100% - 56px - var(--spacing-super-loose) - 40px);

    &-right {
      width: 100%;
    }
  }

  &.is-experience {
    background: none;

    .client-side-wrap__main {
      padding: 0;

      .chat-wrap__main {
        max-width: none;
        box-shadow: none;
      }

      .chat-wrap__main-header {
        max-width: none;
        border-bottom: 0.5px solid var(--color-divider-normal);
      }

      .bg-container {
        width: 100%;
        max-width: 860px;
        align-self: center;
        position: relative;

        .chat-wrap__main-head {
          position: static;
        }
      }
    }

    .client-side-wrap__footer {
      .service-agreement {
        padding-top: 0;
      }
    }
  }
}

.chat-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  &__main {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 400px;
    height: 85%;
    min-height: calc(100% - 56px);
    overflow: hidden;
    border-radius: 12px;
    // margin-right: 35%;
    // box-shadow: -4px -4px 8px rgba(255, 255, 255, 0.9), -24px -24px 48px rgba(255, 255, 255, 0.9), 24px 24px 48px rgba(18, 54, 153, 0.1);
    box-shadow: 0px 24px 48px rgba(18, 54, 153, 0.1);

    &.is-voice {
      height: calc(100% - 40px) !important;
    }

    &.experience-height {
      min-height: calc(100% - 56px);
    }

    &.unavailable {
      background: var(--color-bg-0);
    }

    .bg-container {
      height: calc(100% - 56px);
      // height: calc(100% - 28px);
      background: var(--color-bg-0);
      position: relative;
      display: flex;
      flex-direction: column;
    }

    &-chat-content {
      height: calc(100% - 80px - 40px);
      display: flex;
      justify-content: flex-end;
      align-items: flex-end;
      flex: 1;
      overflow-y: auto;
    }

    &-content {
      height: calc(100% - 80px - 40px);
      display: flex;
      justify-content: flex-end;
      align-items: flex-end;
      flex: 1;
      overflow-y: auto;
    }

    &-footer {
      position: relative;
      z-index: 3;
    }
  }

  &.is-experience {
    background: none;

    .client-side-wrap__main {
      padding: 0;

      .chat-wrap__main {
        max-width: none;
      }

      .chat-wrap__main-header {
        max-width: none;
      }

      .bg-container {
        width: 860px;
        align-self: center;
        position: relative;

        .chat-wrap__main-head {
          width: 860px;
          position: fixed;
          left: 50%;
          transform: translateX(-50%);
        }
      }
    }
  }
}

.chat-wrap.is-mobile {
  .chat-wrap__main {
    width: 100%;
    height: 100%;
    min-height: unset;
    border-radius: 0;

    .service-agreement {
      box-sizing: border-box;
      width: 100%;
      position: fixed;
      bottom: 0;
    }
  }

  .bg-container {
    height: calc(100% - 28px);
  }
}

.chat-wrap.is-web {
  .chat-layout {
    width: 100%;
    height: 100%;
    max-width: 1280px;
    display: flex;
  }

  .chat-wrap__main {
    width: 100%;
    height: 100%;
  }

  .workspace-active {
    box-shadow: 0px 24px 48px rgba(18, 54, 153, 0.1);

    .chat-wrap__main {
      width: 50%;
      border-top-left-radius: 12px;
      border-bottom-left-radius: 12px;
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;
      box-shadow: none;
    }

    .workspace-container {
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
      border-top-right-radius: 12px;
      border-bottom-right-radius: 12px;
      min-height: calc(100% - 56px);
      background: var(--color-bg-0);
    }
  }
}
</style>
